#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <pthread.h>
#include <math.h>
#include "prefetch_lib.h"
#include <time.h>
#include <pthread.h>

#define N (32768/2)
#define NUMINTS  (N * N)
#define FILESIZE (NUMINTS * sizeof(double))
#define TOTALSIZE (4294967296/2)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


double *a, *w, *v;

int F()
{
   time_t t = time(0);
   int n = N;
   int i, j, k, p;
   double *p_k, *p_row, *p_col;
 
   for (k = 0, p_k = a; k < n; p_k += n, k++) {
         if (k % 2 == 0) {
           time_t n = time(0);
           printf("[%lu] in k loop; k = %d done in %lu\n", pthread_self(), k, n - t);
           t = n;
         }
   
      for (j = k; j < n; j++) {
         
         for (p = 0, p_col = a; p < k; p_col += n,  p++) {
            *(p_k + j) -= *(p_k + p) * *(p_col + j);
         }
      }
      //if ( *(p_k + k) == 0.0 ) return -1;
      for (i = k+1, p_row = p_k + n; i < n; p_row += n, i++) {
         for (p = 0, p_col = a; p < k; p_col += n, p++) {
            *(p_row + k) -= *(p_row + p) * *(p_col + k);
         }
         *(p_row + k) /= *(p_k + k);
      }  
   }
   return 0;
}



int main(int argc, char *argv[])
{
    void *ret_mmap;
    int f, fda, fdb, i;

    turn_logging(1);
    fetch_init();
    a = (double*)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fda = open64("a", O_RDWR), 0);

    printf("a: %x-%x\n", (unsigned int)a >> 12, (unsigned int)(a + N * N) >> 12);

    madvise(a, FILESIZE, MADV_RANDOM);

    f = F();

    munmap(a, FILESIZE);

    close(fda);
    
    return f;
}
